home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Graphics / NXPlot3d / Source / DensView.m.bak < prev    next >
Text File  |  1994-02-07  |  9KB  |  334 lines

  1. /* DensView.m  Copyright 1992 Steve Ludtke */
  2.  
  3. /* This object works by taking passed data and rendering it into an NXImage */
  4. /* which is then composited to the screen as necessary. When the view is    */
  5. /* resized, the user coordinate system is reset to unit size. Areas can be  */ 
  6. /* selected by dragging with the mouse. A zoomTo:::: message will be sent to*/ 
  7. /* the delegate with the resulting area. This view now supports both density*/
  8. /* and simple contour plots (2/94) */
  9.  
  10. #import "Plot3DView.h"
  11. #import "DensView.h"
  12.  
  13. #import <stdio.h>
  14. #import <string.h>
  15. #import <libc.h>
  16. #import <math.h>
  17. #import <appkit/appkit.h>
  18. #import <dpsclient/psops.h>
  19.  
  20. char hex[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
  21.  
  22. extern id NXApp;
  23.  
  24. float sgn(float x) { if (x>=0) return(1.0); return(0); }
  25.  
  26. @implementation DensView
  27.  
  28. -initFrame:(NXRect *)myrect
  29. {
  30. [super initFrame:myrect];
  31. [self setDrawSize:1.0 :1.0];    /* set size and origin so view is a "unit" */
  32. [self setDrawOrigin:0.0 :0.0];    /* coordinate system */
  33. point.y=point.x=0.0;        /* origin of image when composited */
  34. buf=NULL;
  35. data=NULL;
  36. image=nil;            /* new image is created by -setData::::: */
  37. mode=0;
  38. dmode=DM_DENSITY;
  39. return self;
  40. }
  41.  
  42. -superviewSizeChanged:(const NXSize *)oldsize
  43. {
  44. [super superviewSizeChanged:oldsize];
  45. [self setDrawSize:1.0 :1.0];            /* fix drawing size */
  46. [self setData:nx :ny :data :minZ :maxZ :rec :rec2];    /* re-render NXImage */
  47. return self;
  48. }
  49.  
  50. /* essentially all this method has to do is composite the NXImage to the */
  51. /* screen. */
  52. -drawSelf:(NXRect *)rects :(int)rectCount
  53. {
  54.  
  55. if (buf==NULL||data==NULL||image==nil) {
  56.     PSsetgray(NX_WHITE);
  57.     NXRectFill(&bounds);
  58.     return(self);
  59. }
  60.  
  61. if (mode) {
  62.     DPSWritePostScript(DPSGetCurrentContext(), buf, strlen(buf));
  63. }
  64. else [image composite:NX_COPY toPoint:&point];
  65.  
  66. return self;
  67. }
  68.  
  69. /* This method receives data and generates the NXImage */
  70. -setData:(int)Nx :(int)Ny :(float *)Data :(float)MinZ :(float)MaxZ :(NXRect)Rec :(NXRect)Rec2
  71. {
  72. NXStream *str;
  73. static char s[220];
  74. int i,j,k,n,d,sl;
  75. float lev,x[4],y[4],p[4];
  76.  
  77. /* Make sure our postscript buffer is big enough */
  78. if ((Nx*Ny)>bufs) {
  79.     if (buf!=NULL) free(buf);
  80.     buf=malloc(Nx*Ny*2+Nx*Ny/20+600);
  81.     bufs=Nx*Ny;
  82. }
  83. data=Data;
  84. nx=Nx;
  85. ny=Ny;
  86. minZ=MinZ;
  87. maxZ=MaxZ;
  88. rec=Rec;
  89. rec2=Rec2;
  90.  
  91. /* Since everything conforms properly, it would be quite easy to */
  92. /* generate an EPS file from this data ... */
  93. sprintf(s,"%%!PS-Adobe-2.0 EPSF-2.0\n%%%%Origin:0 0\n%%%%BoundingBox: 0 0 %f %f\n%%%%EndComments\n/picstr 1 string def\ngsave\n", frame.size.width,frame.size.height);
  94. strcpy(buf,s);
  95. sprintf(s,"%f %f scale ",frame.size.width,frame.size.height);
  96. strcat(buf,s);
  97. strcat(buf,"1 setgray 0 0 moveto 1 0 lineto 1 1 lineto 0 1 lineto fill\n");
  98.  
  99. if (dmode&DM_DENSITY) {
  100.     sprintf(s,"gsave %f %f translate\n",-.5/(float)(nx-1),-.5/(float)(ny-1));
  101.     strcat(buf,s);
  102.     sprintf(s,"%f %f translate %f %f scale\n", 
  103.         (rec.origin.x-rec2.origin.x)/rec2.size.width, 
  104.         (rec.origin.y-rec2.origin.y)/rec2.size.height,
  105.         rec.size.width/rec2.size.width,rec.size.height/rec2.size.height);
  106.     strcat(buf,s);
  107.  
  108.     sprintf(s,"%d %d 8 [%d 0 0 %d 0 0] {currentfile picstr readhexstring pop} image\n",nx,ny,nx-1,ny-1);
  109.     strcat(buf,s);
  110.     i=strlen(buf);
  111.     for (n=0; n<(nx*ny); n++) {
  112.         if (n%100==0) buf[i++]='\n';
  113.         d=255*(data[n]-minZ)/(maxZ-minZ);
  114.         if (d>255) d=255;
  115.         if (d<0) d=0;
  116.         buf[i++]=hex[d>>4];
  117.         buf[i++]=hex[d&15];
  118.     }
  119.     buf[i]=0;
  120.     strcat(buf," grestore\n");
  121. }
  122. if (dmode&DM_CONTOUR) {
  123.     sprintf(s,"%f %f translate %f %f scale\n", 
  124.         (rec.origin.x-rec2.origin.x)/rec2.size.width, 
  125.         (rec.origin.y-rec2.origin.y)/rec2.size.height,
  126.         rec.size.width/rec2.size.width,rec.size.height/rec2.size.height);
  127.     strcat(buf,s);
  128.     sl=strlen(buf);
  129.     strcat(buf,".002 setlinewidth 0 setgray /m {moveto} def /d {lineto} def\n");
  130.     sl=strlen(buf);
  131.     lev=(maxZ+minZ)/2.0;
  132.     for (lev=(maxZ-minZ)/20.0+minZ; lev<MaxZ; lev+=(maxZ-minZ)/10.0) {
  133.     for (i=0; i<nx-1; i++) {
  134.         for (j=0; j<ny-1; j++) {
  135.             p[0]=data[i+j*nx]-lev;
  136.             p[1]=data[i+j*nx+1]-lev;
  137.             p[2]=data[i+j*nx+nx]-lev;
  138.             p[3]=data[i+j*nx+nx+1]-lev;
  139.             if ((sgn(p[0])+sgn(p[1])+sgn(p[2])+sgn(p[3]))!=4 
  140.                 &&((sgn(p[0])+sgn(p[1])+sgn(p[2])+sgn(p[3]))!=0)) {
  141.                 k=0;
  142.                 if ((p[0]>0&&p[1]<0)||(p[1]>0&&p[0]<0)) {
  143.                     x[k]=(p[0]/(p[0]-p[1])+(float)i)/(float)(nx-1);
  144.                     y[k]=(float)j/(float)(ny-1);
  145.                     k++;
  146.                 }
  147.                 if ((p[2]>0&&p[3]<0)||(p[3]>0&&p[2]<0)) {
  148.                     x[k]=(p[2]/(p[2]-p[3])+(float)i)/(float)(nx-1);
  149.                     y[k]=(float)(j+1)/(float)(ny-1);
  150.                     k++;
  151.                 }
  152.                 if ((p[0]>0&&p[2]<0)||(p[2]>0&&p[0]<0)) {
  153.                     x[k]=(float)i/(float)(nx-1);
  154.                     y[k]=(p[0]/(p[0]-p[2])+(float)j)/(float)(ny-1);
  155.                     k++;
  156.                 }
  157.                 if ((p[1]>0&&p[3]<0)||(p[3]>0&&p[1]<0)) {
  158.                     x[k]=(float)(i+1)/(float)(nx-1);
  159.                     y[k]=(p[1]/(p[1]-p[3])+(float)j)/(float)(ny-1);
  160.                     k++;
  161.                 }
  162.                 if (k==2) { 
  163.                     sprintf(s,"%5.3f %5.3f m %5.3f %5.3f d\n", x[0],y[0],x[1],y[1]);
  164.                     strcat(buf,s);
  165.                     sl+=strlen(s);
  166.                 }
  167.                 else if (k==4) {
  168.                     sprintf(s,"%5.3f %5.3f m %5.3f %5.3f d %5.3f %5.3f m %5.3f %5.3f d\n",x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[3]);
  169.                     strcat(buf,s);
  170.                     sl+=strlen(s);
  171.                 }
  172.             }
  173.             if (sl>malloc_size(buf)-1000) {
  174.                 buf=realloc(buf,malloc_size(buf)+20000);
  175.             }
  176.         }
  177.     }
  178.     }
  179.     strcat(buf,"stroke\n");
  180. }
  181. strcat(buf,"\ngrestore\n");
  182.  
  183. /* send the postscript we generated to an NXImage. I know this is a messy */
  184. /* way of doing things, but it's leftover from a previous incarnation of  */
  185. /* this object and I didn't feel like rewriting it ... */
  186. str=NXOpenMemory(buf,strlen(buf),NX_READONLY);
  187. if (image!=nil) [image free];
  188. image=[NXImage alloc];
  189. image=[image initFromStream:str];
  190. NXClose(str);
  191.  
  192. /* This is how it used to work */
  193. /*DPSWritePostScript(DPSGetCurrentContext(), buf, i);*/
  194.  
  195. [self display];
  196. return self;
  197. }
  198.  
  199. -saveTiff:sender
  200. {
  201. NXStream *stream;
  202. id rep,im2;
  203. NXRect rect = { 0,0,300.0,300.0 };
  204. NXSize size = { 300.0, 300.0 };
  205.  
  206. im2=[[NXImage alloc] initSize:&size];
  207. [im2 setDataRetained:YES];
  208. rep=[NXBitmapImageRep alloc];
  209. [rep initData:NULL pixelsWide:320 pixelsHigh:320 bitsPerSample:8 samplesPerPixel:3 hasAlpha:NO isPlanar:NO colorSpace:NX_RGBColorSpace bytesPerRow:960 bitsPerPixel:24];
  210. [im2 useRepresentation:rep];
  211. /*[im2 useCacheWithDepth:NX_TwentyFourBitRGBDepth];
  212. rep=[im2 lastRepresentation];
  213. [rep setAlpha:NO];*/
  214. [im2 lockFocus];
  215. /*[image composite:NX_COPY toPoint:&rect.origin];*/
  216. PSsetgray(.5);
  217. PSmoveto(0,0);
  218. PSlineto(100.0,100.0);
  219. PSlineto(0,100.0);
  220. PSstroke();
  221. [im2 unlockFocus];
  222. /*printf("Alpha:%d bits:%d colors:%d\n",[rep hasAlpha],[rep bitsPerSample],[rep numColors]);*/
  223.  
  224. if (image==nil) return self;
  225. stream=NXOpenMemory(NULL,0,NX_WRITEONLY);
  226. [im2 writeTIFF:stream allRepresentations:YES];
  227. NXSaveToFile(stream,"/users/steve/test.tiff");
  228. NXClose(stream);
  229.  
  230. [im2 free];
  231. return self;
  232. }
  233.  
  234. -savePS:sender
  235. {
  236. FILE *out;
  237.  
  238. out=fopen("/users/steve/test.eps","w");
  239. fwrite(buf,strlen(buf),1,out);
  240. fclose(out);
  241. return self;
  242. }
  243.  
  244. /* Allows the user to select an area of the plot to be passed to the */
  245. /* delegate via a zoomTo:::: message. */
  246. -mouseDown:(NXEvent *)oevent 
  247. {
  248. int oldMask,loop=1;
  249. NXEvent *event,evs;
  250. float f,dash[2] = { SS,SS };
  251.  
  252. evs=*oevent;
  253. oevent=&evs;
  254. [self convertPoint:&oevent->location fromView:nil];
  255.  
  256. oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
  257.  
  258. while (loop) {
  259.     event = [NXApp getNextEvent:(NX_LMOUSEUPMASK | NX_LMOUSEDRAGGEDMASK)];
  260.     [self convertPoint:&event->location fromView:nil];
  261.  
  262.         switch (event->type) {
  263.         case NX_LMOUSEUP:
  264.                 loop = 0;
  265.         if (event->location.x<oevent->location.x) {
  266.             f=event->location.x;
  267.             event->location.x=oevent->location.x; 
  268.             oevent->location.x=f; 
  269.         }
  270.         if (event->location.y<oevent->location.y) {
  271.             f=event->location.y;
  272.             event->location.y=oevent->location.y; 
  273.             oevent->location.y=f; 
  274.         }
  275.         if (event->location.x-oevent->location.x<.02) break;
  276.         if (event->location.y-oevent->location.y<.02) break;
  277.         [delegate zoomTo:oevent->location.x :oevent->location.y :event->location.x :event->location.y];
  278.             break;
  279.         case NX_LMOUSEDRAGGED:
  280.         [self lockFocus];
  281.         PSsetlinewidth(0.0);
  282.         [image composite:NX_COPY toPoint:&point];
  283.  
  284.         PSmoveto(oevent->location.x,oevent->location.y);
  285.         PSlineto(event->location.x,oevent->location.y);
  286.         PSlineto(event->location.x,event->location.y);
  287.         PSlineto(oevent->location.x,event->location.y);
  288.         PSlineto(oevent->location.x,oevent->location.y);
  289.  
  290.         PSsetgray(1.0);
  291.         PSsetdash(dash,2,0.0);
  292.         PSgsave();
  293.         PSstroke();
  294.         PSgrestore();
  295.  
  296.         PSsetgray(0.0);
  297.         PSsetdash(dash,2,SS);
  298.         PSstroke();
  299.  
  300.         [self unlockFocus];
  301.         [window flushWindow];
  302.         break;
  303.     }
  304.     
  305. }
  306. [window setEventMask:oldMask];
  307. return self;
  308. }
  309.  
  310. -setDenFlag:sender
  311. {
  312. dmode=0;
  313. if ([[sender cellAt:0 :0] intValue]) dmode+=DM_DENSITY;
  314. if ([[sender cellAt:1 :0] intValue]) dmode+=DM_CONTOUR;
  315. [self setData:nx :ny :data :minZ :maxZ :rec :rec2];    /* re-render NXImage */
  316. return self;
  317. }
  318.  
  319. -(int)acceptsFirstMouse {
  320. return (YES);
  321. }
  322.  
  323. -printPSCode:sender
  324. {
  325. mode=1;
  326. [self setDrawSize:frame.size.width :frame.size.height];    
  327. [super printPSCode:sender];
  328. [self setDrawSize:1.0 :1.0];    /* set size and origin so view is a "unit" */
  329. mode=0;
  330. return self;
  331. }
  332.  
  333. @end
  334.